package com.paic.mhis.hcpms.common.validator;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.paic.mhis.hcpms.agreement.healthcareprovider.util.ValidatorUtil;
import com.paic.pafa.app.biz.bo.validation.ValidStatus;
import com.paic.pafa.app.biz.bo.validation.Validator;

public abstract class MapValidator implements Validator
{

	public ValidStatus validate(Object fieldMap)
	{
		return checkMap((Map<Object, Object>)fieldMap);
	}

	abstract protected ValidStatus checkMap(Map<Object, Object> fieldMap);

	/**
	 * <p>
	 * 必输校验,默认返回99
	 * </p>
	 * 
	 * @param key
	 * @param msg
	 * @return MapValidator
	 */
	public static MapValidator require(final String key, final String msg)
	{
		return require(key, msg, "99");
	}

	/**
	 * <p>
	 * 必输校验
	 * </p>
	 * 
	 * @param key
	 * @param msg
	 * @param code
	 * @return MapValidator
	 */
	public static MapValidator require(final String key, final String msg, final String code)
	{
		return new MapValueNotEmpty(key, msg, code);
	}

	/**
	 * <p>
	 * 值是否在可选范围内字符以|符号分割
	 * </p>
	 * 
	 * @param key
	 * @param values
	 * @param msg
	 * @param code
	 * @return MapValidator
	 */
	public static MapValidator matchScope(final String key, final String values, final String msg)
	{
		return matchScope(key, values, msg, "99");
	}

	/**
	 * <p>
	 * 值是否在可选范围内字符以|符号分割
	 * </p>
	 * 
	 * @param key
	 * @param values
	 * @param msg
	 * @param code
	 * @return MapValidator
	 */
	public static MapValidator matchScope(final String key, final String values, final String msg, final String code)
	{
		return new MapValueValidator(key, msg, code)
		{
			protected boolean validateSuccess(Object val)
			{
				if(StringUtils.isNotBlank(values))
				{
					boolean flag = false;
					String[] strings = values.split("\\|");
					for(int i = 0; i < strings.length; i++)
					{
						if(val.equals(strings[i]))
						{
							flag = true;
						}
					}
					return flag;
				}
				return false;
			}
		};
	}

	/**
	 * <p>
	 * 日期格式校验
	 * </p>
	 * 
	 * @param key
	 * @param pattern
	 * @param msg
	 * @param code
	 * @return MapValidator
	 */
	public static MapValidator date(final String key, final String msg, final String code)
	{
		return new MapValueDateFormat(key, msg, code);
	}

	/**
	 * <p>
	 * 日期格式校验
	 * </p>
	 * 
	 * @param key
	 * @param pattern
	 * @param msg
	 * @return MapValidator
	 */
	public static MapValidator date(final String key, final String msg)
	{
		return date(key, msg, "99");
	}

	/**
	 * <p>
	 * 正整数校验（默认最大位数10位）
	 * </p>
	 * 
	 * @param key
	 * @param msg
	 * @return MapValidator
	 */
	@Deprecated
	public static MapValidator integer(final String key, final String msg)
	{
		return integer(key, 10, msg, "99");
	}

	/**
	 * <p>
	 * 正整数校验
	 * </p>
	 * 
	 * @param key
	 * @param max
	 * @param msg
	 * @return MapValidator
	 */
	public static MapValidator integer(final String key, final int max, final String msg)
	{
		return integer(key, max, msg, "99");
	}

	/**
	 * <p>
	 * 正整数校验
	 * </p>
	 * 
	 * @param key
	 * @param msg
	 * @param code
	 * @return MapValidator
	 */
	public static MapValidator integer(final String key, final int max, final String msg, final String code)
	{
		return new MapValueValidator(key, msg, code)
		{
			protected boolean validateSuccess(Object value)
			{
				if(null == value)
				{
					return true;
				}
				String tmpValue = null;
				if(value instanceof Number)
				{
					tmpValue = String.valueOf(value);
				}
				else
				{
					tmpValue = (String)value;
				}
				if(ValidatorUtil.isPlusInteger(tmpValue) && Integer.parseInt(tmpValue) <= max)
				{
					return true;
				}
				return false;
			}

			protected Object[] getArguments(Object val)
			{
				return new Object[]{val};
			}
		};
	}

	/**
	 * <p>
	 * 数字校验（能转换BigDecimal）
	 * </p>
	 * 
	 * @param key
	 * @param msg
	 * @param code
	 * @return MapValidator
	 */
	public static MapValidator number(final String key, final String msg, final String code)
	{
		return new MapValueValidator(key, msg, code)
		{
			protected boolean validateSuccess(Object val)
			{
				if(null == val)
					return true;
				try
				{
					new BigDecimal((String)val);
					return true;
				}
				catch(Exception ex)
				{
					return false;
				}
			}

			protected Object[] getArguments(Object val)
			{
				return new Object[]{val};
			}
		};
	}

	/**
	 * <p>
	 * 数字类型（限制位数及小数位）
	 * </p>
	 * 
	 * @param key
	 * @param max
	 *            最大位数(不包含小数位)
	 * @param digit
	 *            保留小数位
	 * @param msg
	 * @return MapValidator
	 */
	public static MapValidator number(final String key, final int max, final int digit, final String msg)
	{
		return number(key, max, digit, msg, "99");
	}

	/**
	 * <p>
	 * 数字类型（限制位数及小数位）
	 * </p>
	 * 
	 * @param key
	 * @param max
	 *            最大位数(不包含小数位)
	 * @param digit
	 *            保留小数位
	 * @param msg
	 * @param code
	 * @return MapValidator
	 */
	public static MapValidator number(final String key, final int max, final int digit, final String msg,
			final String code)
	{
		return new MapValueValidator(key, msg, code)
		{
			@Override
			protected boolean validateSuccess(Object val)
			{
				if(null==val || StringUtils.isBlank(String.valueOf(val)) )
				{
					return true;
				}
				String obj = String.valueOf(val);
				return obj.matches("^-?[0-9]{0," + (max-digit) + "}.[0-9]{0," + digit + "}$") || 
						obj.matches("^[0-1]$");
			}
		};
	}

	/**
	 * <p>
	 * 数字校验（能转换BigDecimal），出错默认code:99
	 * </p>
	 * 
	 * @param key
	 * @param msg
	 * @return MapValidator
	 */
	public static MapValidator number(final String key, final String msg)
	{
		return number(key, msg, "99");
	}

	/**
	 * <p>
	 * 长度校验
	 * </p>
	 * 
	 * @param key
	 * @param min
	 * @param max
	 * @param msg
	 * @param code
	 * @return MapValidator
	 */
	public static MapValidator minAndMaxLength(final String key, final int min, final int max, final String msg,
			final String code)
	{
		return new MapValueValidator(key, msg, code)
		{
			protected boolean validateSuccess(Object value)
			{
				if(null == value || "".equals(value))
				{
					return true;
				}
				String tmpValue = (String)value;
				return tmpValue.length() >= min && tmpValue.length() <= max;
			}

			protected Object[] getArguments(Object val)
			{
				return new Object[]{val};
			}
		};
	}

	/**
	 * <p>
	 * 长度校验
	 * </p>
	 * 
	 * @param key
	 * @param min
	 * @param max
	 * @param msg
	 * @return MapValidator
	 */
	public static MapValidator minAndMaxLength(final String key, final int min, final int max, final String msg)
	{
		return minAndMaxLength(key, min, max, msg, "99");
	}

	/**
	 * <p>
	 * 最大长度校验
	 * </p>
	 * 
	 * @param key
	 * @param length
	 * @param msg
	 * @param code
	 * @return MapValidator
	 */
	public static MapValidator maxLength(final String key, final int length, final String msg, final String code)
	{
		return new MapValueValidator(key, msg, code)
		{
			protected boolean validateSuccess(Object val)
			{
				if(null == val)
					return true;
				String s = String.valueOf(val);
				return s.length() <= length;
			}

			protected Object[] getArguments(Object val)
			{
				return new Object[]{val};
			}
		};
	}

	/**
	 * <p>
	 * 最大长度校验，出错默认code:99
	 * </p>
	 * 
	 * @param key
	 * @param length
	 * @param msg
	 * @return MapValidator
	 */
	public static MapValidator maxLength(final String key, final int length, final String msg)
	{
		return maxLength(key, length, msg, "99");
	}

	/**
	 * <p>
	 * 最小长度校验
	 * </p>
	 * 
	 * @param key
	 * @param length
	 * @param msg
	 * @param code
	 * @return MapValidator
	 */
	public static MapValidator minLength(final String key, final int length, final String msg, final String code)
	{
		return new MapValueValidator(key, msg, code)
		{
			protected boolean validateSuccess(Object val)
			{
				if(null == val)
					return false;
				String s = String.valueOf(val);
				return s.length() >= length;
			}

			protected Object[] getArguments(Object val)
			{
				return new Object[]{val};
			}
		};
	}

	/**
	 * <p>
	 * 最小长度校验，出错默认code:99
	 * </p>
	 * 
	 * @param key
	 * @param length
	 * @param msg
	 * @return MapValidator
	 */
	public static MapValidator minLength(final String key, final int length, final String msg)
	{
		return minLength(key, length, msg, "99");
	}

	/**
	 * <p>
	 * 相等校验
	 * </p>
	 * 
	 * @param key
	 * @param value
	 * @param msg
	 * @param code
	 * @return Validator
	 */
	public static Validator equal(final String key, final String value, final String msg, final String code)
	{
		return new MapValueValidator(key, msg, code)
		{
			protected boolean validateSuccess(Object val)
			{
				return value.equals(val);
			}

		};
	}

	/**
	 * <p>
	 * 包含校验
	 * </p>
	 * 
	 * @param key
	 * @param value
	 * @param msg
	 * @param code
	 * @return Validator
	 */
	public static Validator contain(final String key, final Collection value, final String msg, final String code)
	{
		return new MapValueValidator(key, msg, code)
		{
			protected boolean validateSuccess(Object val)
			{
				return value.contains(val);
			}

			protected Object[] getArguments(Object val)
			{
				return new Object[]{val};
			}
		};
	}

	/**
	 * 姓名校验(包括中文姓名和英文姓名)
	 * 
	 * @param key
	 * @param msg
	 * @return Validator
	 */
	public static Validator checkName(final String key, final String msg)
	{

		return checkName(key, msg, "99");
	}

	/**
	 * @param key
	 * @param msg
	 * @param code
	 * @return Validator
	 */
	public static Validator checkName(final String key, final String msg, String code)
	{
		return new MapValueValidator(key, msg, code)
		{
			protected boolean validateSuccess(Object val)
			{
				if(val == null)
					return true;
				if(!(val instanceof String))
					return false;
				if(val.equals(""))
					return true;
				
				return true;
			}

			protected Object[] getArguments(Object val)
			{
				return new Object[]{val};
			}
		};
	}

	/**
	 * 校验电话号码（包括手机和固话）
	 * 
	 * @param key
	 * @param msg
	 * @return
	 */
	public static Validator checkPhone(final String key, final String msg)
	{

		return checkPhone(key, msg, "99");
	}

	/**
	 * 校验电话号码（包括手机和固话）
	 * 
	 * @param key
	 * @param msg
	 * @param code
	 * @return
	 */
	public static Validator checkPhone(final String key, final String msg, String code)
	{
		return new MapValueValidator(key, msg, code)
		{
			@Override
			protected boolean validateSuccess(Object val)
			{
				if(val == null)
					return true;
				if(!(val instanceof String))
					return false;
				if(val.equals(""))
					return true;
				return true;
			}

			protected Object[] getArguments(Object val)
			{
				return new Object[]{val};
			}
		};
	}

	public static Validator integer(String key, long max, String msg) {
		return Long(key, max, msg, "99");
	}

	private static Validator Long(final String key, final long max, final String msg, final String code) {
		return new MapValueValidator(key, msg, code)
		{
			protected boolean validateSuccess(Object value)
			{
				if(null == value || "".equals(value))
				{
					return true;
				}
				String tmpValue = null;
				if(value instanceof Number)
				{
					tmpValue = String.valueOf(value);
				}
				else
				{
					tmpValue = (String)value;
				}
				if(ValidatorUtil.isPlusInteger(tmpValue) && Long.parseLong(tmpValue) <= max)
				{
					return true;
				}
				return false;
			}

			protected Object[] getArguments(Object val)
			{
				return new Object[]{val};
			}
		};
	}
}
